package com.bigflexlib.core.os.call
{
	
	
	import flash.events.IEventDispatcher;
	
	import com.bigflexlib.core.os.thread.Thread;
	import com.bigflexlib.x.flash.events.EventHookEvent;
	import com.bigflexlib.x.flash.events.EventListenerProxy;
	import com.bigflexlib.x.flash.events.EventListenerSpec;
	
	
	
	public class AsyncCallWithListener extends AsyncCall
	{
		
		
		
		private var _dispatcher:IEventDispatcher;
		public function get dispatcher( ):IEventDispatcher
		{
			return _dispatcher;
		}
		
		private var _eventListenerSpecs:Array;
		public function get eventListenerSpecs( ):Array
		{
			return _eventListenerSpecs;
		}
		
		
		
		
		private var proxies:Array = [];
		
		
		
		public function AsyncCallWithListener( thread:Thread, func:Function, args:Array=null, dispatcher:IEventDispatcher=null, eventListenerSpecs:Array=null, processingTarget:*=undefined )
		{
			super( thread, func, args, processingTarget );
		
			_dispatcher = dispatcher;
			_eventListenerSpecs = eventListenerSpecs;
		
		}
		
		
		
		
		override public function execute( ):void
		{
		
			var proxy	:EventListenerProxy;
		
			// add event listeners so we know when the 
			for each ( var spec:EventListenerSpec in _eventListenerSpecs )
			{
				proxy = spec.addToDispatcherUsingProxy( dispatcher );		
				proxy.addEventListener( EventHookEvent.FIRE, proxy_fire );
				proxies.push( proxy );
			}
			
			// execute the call ( or put it on a queue for the processing target?? )
			// we enter "blocked" state
			super.execute( );		

		}
		

		
		private function proxy_fire( event:EventHookEvent ):void
		{
			// we only allow one proxy to fire
			// upon completion queue a new sync call
			// that corresponds to the result handler
			event.preventDefault( );
			
			var proxy:EventListenerProxy = event.target as EventListenerProxy;
			
			thread.queue( proxy.continueOriginalEventFlow , [ event.originalEvent ] );
			
			cleanup( );
			
			
			setState( CallState.COMPLETE );
	
		}
		
		
		
		private function cleanup( ):void
		{
			for each ( var p:EventListenerProxy in proxies )
			{
				p.remove( );				
			}
		}
		
		
		
		
	}

}





